import React, { PureComponent } from 'react';
import {
  Card,
  Button,
  message,
  Empty,
  Select,
  Spin,
  DatePicker,
  Timeline,
  Pagination,
  Tooltip,
  Space,
} from 'antd';
import { Map as GMap } from 'react-amap';
import classNames from 'classnames';
import styles from './style.less';
import 'animate.css/animate.min.css';
import {
  DoubleLeftOutlined,
  DoubleRightOutlined,
  PlayCircleOutlined,
  PauseCircleOutlined,
} from '@ant-design/icons';
import carBlue from '../../../assets/car_blue.png';
import moment from 'moment';
import router from 'umi/router';
import { connect } from 'dva';

const dateFormat = 'YYYY-MM-DD';
const dateFormatNoDay = 'YYYYMM';
const { Option } = Select;
const leftIn = 'animate__animated animate__fadeInLeft animate__fast';
const leftOut = 'animate__animated animate__fadeOutLeft animate__fast';
let isClicked = false;
class Track extends PureComponent<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      dataList: [],
      vin: null,
      loading: false,
      display: true,
      show: true,
      init: true,
      delayShow: false,
      spinning: false,
      selectIndex: null,
      speed: 1000,
      playStatus: null,
      defaultCenter: null,
      marker: null,
      path: null,
      current: 1,
      calendarMap: null,
      userStopDates: [],
    };
  }

  resolve;
  mapPromise = new Promise(resolve => (this.resolve = resolve));

  componentDidMount() {
    this.open();
  }

  componentWillUnmount() {
    if (this.TrackDelayTimer) {
      clearTimeout(this.TrackDelayTimer);
      this.TrackDelayTimer = null;
    }
  }

  areaStyle = {
    fillOpacity: 0.7,
    fillColor: '#4B9248',
    strokeStyle: 'solid',
    strokeColor: '#006633',
  };

  // 初始化围栏
  initFence = async (fenceId: any) => {
    if (!fenceId) {
      return;
    }
    const { ins } = await this.mapPromise;
    const res = await this.props.dispatch({
      type: 'http/getData',
      payload: {
        url: '/electricfence/getfencedetail',
        fenceId: fenceId,
      },
    });

    if (res.statusCode === '0') {
      const data = res.data;
      const something = [];
      if (data.fenceType) {
        // 行政区围栏
        const dist = data.districtList ? data.districtList[0] || {} : {};
        const code = dist.areaCode || dist.cityCode || dist.provinceCode;
        if (!code) {
          return;
        }
        const json = await fetch(`https://geo.datav.aliyun.com/areas_v3/bound/${code}.json`).then(
          e => {
            return e.json();
          },
        );
        const geojson = new AMap.GeoJSON({
          geoJSON: json,
        });
        ins.add(geojson);
        something.push(geojson);
      } else {
        // 地图回显 - 圆
        if (data.circleList) {
          data.circleList.forEach(e => {
            const circle = {
              obj: new AMap.Circle({
                map: ins,
                ...this.areaStyle,
                radius: e.radius,
                center: [e.centerLng, e.centerLat],
              } as any),
            };
            something.push(circle.obj);
          });
        }

        // 地图回显 - 多边形
        if (data.polygonList) {
          data.polygonList.forEach(e => {
            const polygon = {
              obj: new AMap.Polygon({
                map: ins,
                ...this.areaStyle,
                path: e.pointInfos.map(item => new AMap.LngLat(item.lng, item.lat)),
                // draggable: true,
              } as any),
            };
            something.push(polygon.obj);
          });
        }
      }

      ins.setFitView(something);
    }
  };

  open = () => {
    // 初始化围栏
    this.initFence(this.props.location.query.fenceId);

    // 初始化轨迹
    let vin = this.props.location.query.vin;
    // vin = 'LGJE5EE02NM026092';
    // LGJE5EE04NM005146
    this.setState({ vin: vin, display: true, spinning: true, loading: true });
    const { dispatch } = this.props;
    dispatch({
      type: 'fenceVehicleMng/getDataWithRes',
      payload: {
        url: '/electricfence/getuserstoplistbyvin',
        vin: vin,
        date: moment().format(dateFormat),
      },
      callback: (res: any) => {
        this.setState({ loading: false });
        if (res.statusCode == '0') {
          this.setState({ dataList: res.data ? res.data : [] });
        }
      },
    });
    dispatch({
      type: 'fenceVehicleMng/getDataWithRes',
      payload: {
        url: '/electricfence/getuserstopdates',
        vin: vin,
        month: moment().format(dateFormatNoDay),
      },
      callback: (res: any) => {
        let map = new Map();
        if (res.statusCode == '0') {
          map.set(moment().format(dateFormatNoDay), 1);
          this.setState({ userStopDates: res.data ? res.data : [] });
        }
        this.setState({ calendarMap: map });
      },
    });
  };

  close = () => {
    if (this.TrackDelayTimer) {
      clearTimeout(this.TrackDelayTimer);
      this.TrackDelayTimer = null;
    }
    isClicked = false;
    this.setState({ display: false }, () => {
      this.setState(
        {
          dataList: [],
          vin: null,
          loading: false,
          show: true,
          init: true,
          delayShow: false,
          spinning: false,
          selectIndex: null,
          speed: 1000,
          playStatus: null,
          defaultCenter: null,
          marker: null,
          path: null,
          current: 1,
          calendarMap: null,
          userStopDates: [],
        },
        () => {
          router.replace(`${self === top ? '' : '/external'}/electricFence/fenceVehicleMng`);
        },
      );
    });
  };

  changeShow = () => {
    const { show } = this.state;
    if (isClicked) {
      return;
    }
    isClicked = true;
    if (show) {
      this.setState({ show: !show, init: false }, () => {
        isClicked = false;
        this.TrackDelayTimer = setTimeout(() => {
          this.setState({ delayShow: true });
        }, 500);
      });
    } else {
      this.setState({ show: !show, init: false }, () => {
        isClicked = false;
        this.TrackDelayTimer = setTimeout(() => {
          this.setState({ delayShow: false });
        }, 100);
      });
    }
  };

  drawTrack = async (path: any) => {
    const { ins } = await this.mapPromise;
    const { defaultCenter } = this.state;
    ins.clearMap();
    await this.initFence(this.props.location.query.fenceId);
    this.setState({ marker: null, path: null, playStatus: null });
    if (path && path.length > 0) {
      const listArr: any[] = path.map((item: any) => ([item.lon_gcj02, item.lat_gcj02]));
      console.log('listArr', listArr)
      let list = listArr[0];
      const carMarker = new AMap.Marker({
        map: ins,
        position: [list[0], list[1]],
        icon: carBlue,
        offset: new AMap.Pixel(-26, -13),
        autoRotation: true,
        angle: this.getDirc(listArr, ins),
      } as any);
      const polyline = new AMap.Polyline({
        map: ins,
        path: listArr,
        showDir: true,
        strokeColor: '#28F', //线颜色
        strokeWeight: 6, //线宽
      });
      let passedPolyline = new AMap.Polyline({
        map: ins,
        strokeColor: '#AF5', //线颜色
        strokeWeight: 6, //线宽
        showDir: true,
      });
      carMarker.on('moving', function(e) {
        passedPolyline.setPath(e.passedPath);
      });
      ins.setFitView([carMarker, polyline]);
      this.setState({ marker: carMarker, path: listArr });
    } else {
      ins.setZoomAndCenter(17, defaultCenter);
    }
  };

  selectDiv = (index: any, startTime: any, endTime: any) => {
    const { selectIndex, vin } = this.state;
    const { dispatch } = this.props;
    if (selectIndex == index) {
      return;
    }
    this.setState({ loading: true, selectIndex: index });
    dispatch({
      type: 'fenceVehicleMng/getDataWithRes',
      payload: {
        url: '/electricfence/getuserstopdetail',
        vin: vin,
        startTime: startTime,
        endTime: endTime,
      },
      callback: (res: any) => {
        this.setState({ loading: false });
        if (res.statusCode == '0') {
          if (res.data && res.data.length > 0) {
            this.drawTrack(res.data);
            // this.drawTrack(
            //   [
            //     [114.173061, 30.593019],
            //     [114.175504, 30.590843],
            //     [114.176654, 30.5919],
            //     [114.178379, 30.593827],
            //     [114.178594, 30.595008],
            //     [114.180175, 30.598739],
            //     [114.178235, 30.601723],
            //     [114.174642, 30.601972],
            //     [114.170114, 30.600293],
            //     [114.179241, 30.598925],
            //     [114.192392, 30.593392],
            //     [114.19347, 30.600231],
            //     [114.205687, 30.596687],
            //     [114.205975, 30.599547],
            //     [114.211077, 30.598925],
            //     [114.212155, 30.603526],
            //     [114.217832, 30.603215],
            //     [114.21812, 30.599423],
            //     [114.21812, 30.595506],
            //   ].map(e => ({ lon: e[0], lat: e[1] })),
            // );
          } else {
            message.error('轨迹数据不存在');
            this.drawTrack(null);
          }
        } else {
          this.drawTrack(null);
        }
      },
    });
  };

  getDirc = (poiList: any, mapIns: any) => {
    let list = this.findTwoDiffPoi(poiList);
    if (list == null) {
      return null;
    } else {
      return this.calcAngle(
        mapIns.lngLatToContainer(poiList[list[0]]),
        mapIns.lngLatToContainer(poiList[list[1]]),
      );
    }
  };

  findTwoDiffPoi = (poiList: any) => {
    if (poiList && poiList.length > 1) {
      let result: any = [];
      let flag = true;
      poiList.map((item: any, index: any) => {
        if (index < poiList.length - 1 && flag) {
          let pointOne = item;
          let pointTwo = poiList[index + 1];
          if (pointOne[0] == pointTwo[0] && pointOne[1] == pointTwo[1]) {
          } else {
            flag = false;
            result.push(index);
            result.push(index + 1);
          }
        }
      });
      if (result && result.length > 0) {
        return result;
      }
    }
    return null;
  };

  calcAngle = (start: any, end: any) => {
    let diff_x = end.x - start.x;
    let diff_y = end.y - start.y;
    return (360 * Math.atan2(diff_y, diff_x)) / (2 * Math.PI) + 360;
  };

  bd_decrypt = (lon: any, lat: any) => {
    let X_PI = (Math.PI * 3000.0) / 180.0;
    let x = lon - 0.0065;
    let y = lat - 0.006;
    let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
    let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
    let gg_lng = z * Math.cos(theta);
    let gg_lat = z * Math.sin(theta);
    return { longitude: gg_lng, latitude: gg_lat };
  };

  onSpeedChange = (value: any) => {
    const { speed, marker } = this.state;
    if (Number(value) == speed) {
      return;
    }
    marker.stopMove();
    this.setState({ speed: Number(value), playStatus: null });
  };

  onPlay = () => {
    const { playStatus, marker, path, speed } = this.state;
    if (playStatus == 'pause') {
      marker.resumeMove();
      this.setState({ playStatus: 'moving' });
    } else {
      marker.moveAlong(path, speed);
      this.setState({ playStatus: 'moving' });
    }
  };

  onPause = () => {
    const { marker, playStatus } = this.state;
    if (playStatus == 'moving') {
      marker.pauseMove();
      this.setState({ playStatus: 'pause' });
    }
  };

  getTableData = (value: any) => {
    const { vin } = this.state;
    const { dispatch } = this.props;
    this.setState({ loading: true });
    dispatch({
      type: 'fenceVehicleMng/getDataWithRes',
      payload: {
        url: '/electricfence/getuserstoplistbyvin',
        vin: vin,
        date: value.format(dateFormat),
      },
      callback: (res: any) => {
        this.setState({ loading: false, selectIndex: null });
        this.drawTrack(null);
        if (res.statusCode == '0') {
          this.setState({ dataList: res.data ? res.data : [], current: 1 });
        } else {
          this.setState({ dataList: [], current: 1 });
        }
      },
    });
  };

  handlePanelChange = (value: any, mode: any) => {
    const { vin, calendarMap, userStopDates } = this.state;
    const { dispatch } = this.props;
    let month = moment(value).format(dateFormatNoDay);
    if (calendarMap && calendarMap.size > 0 && calendarMap.has(month)) {
      return;
    }
    dispatch({
      type: 'fenceVehicleMng/getDataWithRes',
      payload: {
        url: '/electricfence/getuserstopdates',
        vin: vin,
        month: month,
      },
      callback: (res: any) => {
        let map = new Map();
        if (res.statusCode == '0') {
          if (calendarMap) {
            calendarMap.set(month, 1);
          } else {
            map.set(month, 1);
          }
          this.setState({ userStopDates: userStopDates.concat(res.data ? res.data : []) });
        }
        this.setState({ calendarMap: calendarMap ? calendarMap : map });
      },
    });
  };

  render() {
    const {
      loading,
      dataList,
      show,
      init,
      delayShow,
      spinning,
      selectIndex,
      speed,
      marker,
      current,
      userStopDates,
    } = this.state;
    const mapEvent = {
      created: async (ins: any) => {
        await Promise.all([
          // new Promise(resolve => window.AMap.plugin('AMap.MouseTool', resolve)),
          // new Promise(resolve => window.AMap.plugin('AMap.CircleEditor', resolve)),
          // new Promise(resolve => window.AMap.plugin('AMap.PolyEditor', resolve)),
          // new Promise(resolve => window.AMap.plugin('AMap.Geocoder', resolve)),
          // new Promise(resolve => window.AMap.plugin('AMap.Autocomplete', resolve)),
        ]);
        this.resolve({
          ins,
          // tool: new window.AMap.MouseTool(ins),
          // geocoder: new window.AMap.Geocoder({}),
        });
        this.setState({ spinning: false, defaultCenter: ins.getCenter() });
      },
    };
    return (
      <Card
        title="行车轨迹"
        onClose={this.close}
        bodyStyle={{ padding: '12px 24px' }}
        width={900}
        extra={
          <Button size="small" onClick={this.close}>
            关闭
          </Button>
        }
      >
        <Spin spinning={spinning}>
          <div
            style={{ width: '100%', height: 'calc(100vh - 250px)', border: '1px solid #d9d9d9' }}
          >
            {this.state.display ? (
              <GMap ak={'19dbf6ffd63917bac5a923432ed8ca7a'} events={mapEvent} zoom={17}>
                {delayShow ? (
                  <div
                    className={classNames(styles['iconShowDiv'])}
                    style={{ backgroundColor: 'rgb(255, 255, 255, 0.9)' }}
                    onClick={this.changeShow}
                  >
                    {show ? <DoubleLeftOutlined /> : <DoubleRightOutlined />}
                  </div>
                ) : null}
                {marker ? (
                  <div className={classNames(styles['controleDiv'])}>
                    <Space>
                      <Select
                        value={speed}
                        onChange={this.onSpeedChange}
                        style={{ width: 120 }}
                        getPopupContainer={triggerNode => triggerNode.parentNode}
                      >
                        <Option value={100}>100倍速</Option>
                        <Option value={200}>200倍速</Option>
                        <Option value={500}>500倍速</Option>
                        <Option value={1000}>1000倍速</Option>
                        <Option value={5000}>5000倍速</Option>
                        <Option value={10000}>10000倍速</Option>
                      </Select>
                      <Tooltip title="播放动画">
                        <Button
                          type="primary"
                          onClick={this.onPlay}
                          shape="circle"
                          icon={<PlayCircleOutlined />}
                        />
                      </Tooltip>
                      <Tooltip title="暂停动画">
                        <Button
                          type="primary"
                          onClick={this.onPause}
                          shape="circle"
                          icon={<PauseCircleOutlined />}
                        />
                      </Tooltip>
                    </Space>
                  </div>
                ) : null}

                <div
                  className={classNames(
                    styles['searchDiv'],
                    !init ? (!show ? leftOut : leftIn) : null,
                  )}
                  style={{ backgroundColor: 'rgb(255, 255, 255, 0.9)' }}
                >
                  <Spin spinning={loading}>
                    <div className={classNames(styles['iconDiv'])} onClick={this.changeShow}>
                      {show ? <DoubleLeftOutlined /> : <DoubleRightOutlined />}
                    </div>
                    <div style={{ paddingBottom: 10 }}>
                      日期：
                      <DatePicker
                        placeholder="请选择日期"
                        defaultValue={moment()}
                        allowClear={false}
                        getPopupContainer={triggerNode => triggerNode.parentNode}
                        onChange={this.getTableData}
                        onPanelChange={this.handlePanelChange}
                        dateRender={current => {
                          const style: any = {};
                          if (userStopDates && userStopDates.length > 0) {
                            for (let i in userStopDates) {
                              if (current.format(dateFormat) === userStopDates[i]) {
                                style.border = '1px solid #1890ff';
                                style.borderRadius = '50%';
                              }
                            }
                          }
                          return (
                            <div className="ant-calendar-date" style={style}>
                              {current.date()}
                            </div>
                          );
                        }}
                      />
                      {dataList.length > 0 ? (
                        <span style={{ paddingLeft: 20 }}>共 {dataList.length} 条</span>
                      ) : null}
                    </div>
                    {dataList.length > 0 ? (
                      <div
                        className={
                          dataList.length > 10
                            ? classNames(styles['contentPageDiv'])
                            : classNames(styles['contentDiv'])
                        }
                      >
                        {dataList.map((item: any, index: any) => {
                          let end = current * 10;
                          let start = (current - 1) * 10;
                          if (index >= start && index < end) {
                            return (
                              <div
                                key={item.startTimestamp}
                                className={classNames(
                                  styles['trackDiv'],
                                  selectIndex == index ? styles['trackDivSelected'] : null,
                                )}
                                onClick={() =>
                                  this.selectDiv(index, item.startTimestamp, item.endTimestamp)
                                }
                              >
                                <span>
                                  {moment(item.startTime).format('HH:mm')} ~{' '}
                                  {moment(item.endTime).format('HH:mm')}
                                </span>
                                <Timeline style={{ marginTop: 10 }}>
                                  <Timeline.Item dot={<div>起</div>}>
                                    {item.startPointName}
                                  </Timeline.Item>
                                  <Timeline.Item dot={<div>止</div>}>
                                    {item.endPointName}
                                  </Timeline.Item>
                                </Timeline>
                              </div>
                            );
                          }
                        })}
                        {/* <div className={classNames(styles['trackDiv'], selectIndex == 0 ? styles['trackDivSelected'] : null)} onClick={() => this.selectDiv(0)}>
                        <span>12:00 ~ 14:00</span>
                        <Timeline style={{ marginTop: 10 }}>
                          <Timeline.Item dot={<div>起</div>}>湖北省武汉市汉阳区东风大道66号</Timeline.Item>
                          <Timeline.Item dot={<div>止</div>}>Solve initial network problems 2015-09-01</Timeline.Item>
                        </Timeline>
                      </div> */}
                      </div>
                    ) : (
                      <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
                    )}
                    <Pagination
                      style={{ paddingTop: 5.5 }}
                      size="small"
                      total={dataList.length}
                      hideOnSinglePage
                      showSizeChanger={false}
                      current={current}
                      onChange={(page: any) => this.setState({ current: page })}
                    />
                  </Spin>
                </div>
              </GMap>
            ) : null}
          </div>
        </Spin>
      </Card>
    );
  }
}
export default connect()(Track);
